package caj.springboot.service.impl;

import caj.springboot.common.ResultCodeEnum;
import caj.springboot.common.SysConstants;
import caj.springboot.mapper.LogMapper;
import caj.springboot.model.dto.log.LogInsertDTO;
import caj.springboot.model.dto.log.LogSearchDTO;
import caj.springboot.model.dto.log.LogUpdateDTO;
import caj.springboot.model.exception.EntityException;
import caj.springboot.model.mapstruct.LogConverterMapper;
import caj.springboot.model.po.Log;
import caj.springboot.model.vo.LogVO;
import caj.springboot.service.LogService;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @description: log实现类
 * @author: CAJ
 * @time: 2023/12/8 11:41
 */
@Service
@RequiredArgsConstructor
@Validated
@Slf4j
public class LogServiceImpl implements LogService {

    private final LogMapper logMapper;

    private final LogConverterMapper logConverterMapper;


    @Override
    public List<LogVO> getLogList() {
        return logMapper.selectList(null).stream().map(logConverterMapper::logPOToVO).collect(Collectors.toList());
    }

    /**
     * 默认采用更新时间进行排序，可以根据传入的参数更改排序方式，同时可以根据操作方式进行模糊搜索
     */
    @Override
    public IPage<LogVO> getLogPage(@Valid @NotNull(message = "参数不能为空") LogSearchDTO dto) {
        IPage<Log> page = new Page<Log>(dto.getIndex(),dto.getSize());
        page = logMapper.selectPage(page, Wrappers.<Log>lambdaQuery()
                .like(StrUtil.isNotEmpty(dto.getOperatorType()), Log::getOperatorType, dto.getOperatorType())
                .ge(dto.getStartDateGe() != null, Log::getCreateTime, dto.getStartDateGe())
                .le(dto.getStartDateLe() != null, Log::getCreateTime, dto.getStartDateLe())
                .orderByDesc(StrUtil.isEmpty(dto.getOrderBy()) , Log::getUpdateTime) //默认采用更新时间来排序
                .orderBy(dto.getOrderBy() != null && dto.getOrderBy().equals("createTime") && StrUtil.isNotEmpty(dto.getOrder()), isAsc(dto.getOrder()), Log::getCreateTime)
                .orderBy(dto.getOrderBy() != null && dto.getOrderBy().equals("updateTime") && StrUtil.isNotEmpty(dto.getOrder()), isAsc(dto.getOrder()), Log::getUpdateTime)
                .orderBy(dto.getOrderBy() != null && dto.getOrderBy().equals("operatorType") && StrUtil.isNotEmpty(dto.getOrder()), isAsc(dto.getOrder()), Log::getOperatorType));
        // 可以用下面自己写的xml方法来代替上面调用mybatisplus的方法进行分页查询（效果相同）
        // page = logMapper.getLogPageByXml(dto,page);
        List<LogVO> logVOS = page.getRecords().stream().map(logConverterMapper::logPOToVO).collect(Collectors.toList());
        IPage<LogVO> iPage = new Page<>(dto.getIndex(),dto.getSize(), page.getTotal());
        iPage.setRecords(logVOS);
        return iPage;
    }

    @Override
    public boolean insertLog(@Valid @NotNull(message = "参数不能为空") LogInsertDTO dto) {
        Log log = logConverterMapper.logInsertDTOToPO(dto);
        if (logMapper.insert(log) < 1){
            // 这个返回自定义异常，默认设置的自定义异常code
            // throw new LogException.InsertFailed("插入数据失败");
            // 这个也会被自定义异常捕获，但是是自己设置的code
            throw new EntityException.InsertFailed("插入log数据失败");
        }
        return true;
    }

    @Override
    public boolean updateLogById(@Valid @NotNull(message = "参数不能为空") LogUpdateDTO dto) {
        Log log = logMapper.selectById(dto.getId());
        if (log == null){
            throw new EntityException.InsertFailed("不存在该id的数据");
        }
        log = logConverterMapper.logUpdateDTOToPO(dto);
        if (logMapper.updateById(log) < 1){
            throw new EntityException.InsertFailed("修改log数据失败");
        }
        return true;
    }

    @Override
    public boolean deleteLogById(@NotNull(message = "id不能为空") Long id) {
        if (logMapper.deleteById(id) < 1){
            return false;
        }
        return true;
    }

    @Override
    public boolean isAsc(String order) {
        return order == null ? false : order.equals(SysConstants.SORT_ORDER_ASC);
    }
}
